 PAG
*********************************
*  SEGTWOFONE
*********************************

 ORG $C800  ;CODE RUNS HERE

* THIS SPACE IS SHARED WITH THE VIA AND THE RAM.

*************** MESSAGES *************

* THE FOLLOWING STRING IS USED FOR DISPLAYING REGISTER LABELS.

MSGREGA ASC "A="
 DFB EOT
 ASC " X="
 DFB EOT
 ASC " Y="
 DFB EOT
 ASC " S="
 DFB EOT
 ASC " M="
 DFB EOT
 ASC " L="
 DFB EOT
 ASC " P="
 DFB EOT

*THE FOLLOWING STRING IS USED FOR DISPLAYING THE STATUS FLAGS.

FLAGS ASC "NV1BDIZC"

* MESSAGE "BREAKPOINT"

MSGBREAK
 ASC "** BREAK **"
 DFB CR
 DFB EOT

*********************************
* THE FOLLOWING ROUTINES ARE RUN*
* FROM THE CARDS I/O SPACE.     *
*********************************

CXONTFR
 ORG $C080

CXONLOAD
CXONRTI
 STA CXON  ;CXROM ON
CXOKLOAD
CXOKRTI
 CMP $C100  ;ENABLE ACTIVE SLOT, MODIFIED BY ZPAGSAVE

 NOP   ;SET UP DESIRED ROUTINE BEFORE CALLING
 NOP   ;LDA LOWADD,Y; STA LOWADD,Y OR
 NOP   ;PLP, PHP, RTI

 STA SLOTROM  ;CXROM OFF
 RTS

* USED BY REAL TIME COMMAND
RTVECTOR
 BRK   ;USE BREAK HANDLER TO GOTO EXT 

**** END ROUTINES IN I/O SPACE ***

 ORG

*--------------------
MSGMODE EQU *
 DFB CR
 ASC "--- Mode of Operation ---"
 DFB CR,CR

 ASC "Text screen save"
 DFB CR
 ASC "1=on  2=off"
 DFB EOT

 DFB CR
 ASC "CPU"
 DFB CR
 ASC "1=6502  2=65C02  3=65802"
 DFB EOT

 DFB CR
 ASC "I/O slot #"
 DFB CR
 ASC "1:out  2:in/out  3:normal"
 DFB EOT

MSGMODE2
 DFB CR
 ASC "Enter <" ;put current setting in brackets
 DFB EOT
 ASC "> :"
 DFB EOT

*********************************
* THE FOLLOWING ROUTINES ARE
* TRANSFERED INTO EXT RAM SEG0
* IN THIS SAME ADDRESS SPACE.
* THEY ARE RUN FROM ADDRESSES
* $FFA0-$FFXX
*********************************
* ANY $C8 THAT APPEARS IN THIS
* CODE IS CONVERTED TO $CN BY
* THE ROMTORAM LOAD ROUTINE
* SO THE EXT WILL WORK FROM ANY
* SLOT.

DATATFR
 ORG $FFA0

DATACHK HEX 2020

IRQRAM8 JSR CXOFF  ;CXROM OFF
 PHP   ;SAVE CX STATUS
 JMP IRQJUMP  ;GOTO SLOT SPACE

NMIRAM8 JSR CXOFF
 PHP
 JMP NMIJUMP  ;GOTO SLOT SPACE

NMIRAM16
 JSR SET8BIT  ;SET 8 BIT DATA, CXROM OFF
 PHP   ;SAVE CXROM STATUS
 JMP NMI816  ;SLOT SPACE

BRKRAM16
 JSR SET8BIT
 PHP
 JMP BREAK816 ;SLOT SPACE

SET8BIT PHA   ;SAVE 1 OR 2 BYTES
 PHP   ;PUSH 1 BYTE
 PHP   ;PUSH 1 BYTE
 PLA   ;PULL 1 OR 2 BYTES
 BIT DATACHK
 BEQ DATA16  ;16 BIT DATA
*8 BIT DATA
 PLA   ;REMOVE EXTRA PHP
 PLA   ;GET ACC
 BRA CXOFF ;BRA is OK here

* 16 BIT DATA

DATA16 EQU *
 ORA #$20
 HEX 00  ;RUNS AS ORA #$0020
 PHA   ;PUSH 2 BYTES
 PLP   ;SET 8 BIT DATA MODE
 PLA   ;REMOVE EXTRA BYTE
 PLA   ; LOW BYTE ACC
 XBA
 PLA   ;HI BYTE ACC
 XBA   ;TO HI BYTE

CXOFF BIT CXFLAG  ;GET STATUS OF CXROM
 STA SLOTROM  ;TURN OFF CXROM
 CLD
 RTS

 ORG

****************************************
* THIS POINT MUST BE $CA00 OR ABOVE.
****************************************

 DS $CA00-*,$FF

* IF THE ROOM IS NEEDED, PUT CODE HERE AND JUMP TO IT
* FROM OTHER SEGMENTS.

MAINSEG2

* REPLACE THE ORIGINAL INSTRUCTION WITH A BRK COMMAND
* SET CARRY IF WE HAVE A BREAK THERE ALREADY

PUTBREAK
 JSR VALIDAD  ;ALREADY HAVE A BRK THERE?,PUT Y IN YBUFF
 BMI PUTBRK2  ;IF NO
 JSR REPLACE  ;IF YES, REMOVE OLD BRK
PUTBRK2 LDA SBTYPE  ;GET SB TYPE
 CMP #"I"  ;IS IT IMPLIED
 BEQ UPDATE  ;IF YES

 LDA LETTER1
 STA LOWADD  ;SETUP POINTER
 LDA LETTER2
 STA HIADD
 LDA LETTER3
 STA PBRADD  ;BANK #

 LDY #0
 JSR TRANSFR2 ;READ DATA AT BREAKPOINT ADDRESS
 DFB LDAINDYC ;CODE
 STA DATABRK  ;SAVE ORIG DATA
 TYA   ;LOAD ACC WITH 00
 JSR TRANSFR2 ;STORE BREAK
 DFB STAINDYC ;CODE
 JSR TRANSFR2 ;VERIFY THAT LOCATION WAS RAM, SET Z BIT IF OK
 DFB LDAINDYC ;CODE
 BNE PUTDONE  ;ERROR, "NOT RAM"
 INC REALBRK  ;COUNT REAL BREAKS

* UPDATE THE BREAKPOINT LIST.

UPDATE LDY POINT  ;BRK STACK POINTER
 STX XBUFF  ;SAVE
 LDX #7
:LOOP LDA DATABRK,X ;BRK STACK INFO
 PHA   ;ON SYSTEM STACK
 DEX
 BPL :LOOP

 LDX SLOTN0
****************************************
* !!! ALERT !!! SEGMENT DEPENDENT CODE *
****************************************
 LDA #%01100010 ;RAM6, ROM2
 STA SEGMBASE,X
* PULL BRK INFO OFF SYSTEM STACK AND PUT IN BRK STACK
 PLA
 STA BRKDATA,Y
 PLA
 STA BRKLOW,Y
 PLA
 STA BRKHI,Y
 PLA
 STA BRKPBR,Y
 PLA
 STA BRKTGLOW,Y
 STA BRKPASLO,Y
 PLA
 STA BRKTGHI,Y
 STA BRKPASHI,Y
 PLA   ;SKIP LETTER6
 PLA
 STA BRKTYPE,Y
****************************************
* !!! ALERT !!! SEGMENT DEPENDENT CODE *
****************************************
 LDA #%00000010 ;RAM0, ROM2
 STA SEGMBASE,X
 INY
 STY POINT  ;UPDATE BRK STACK POINTER
 LDX XBUFF  ;RESTORE
 LDA #0  ;SET Z BIT
PUTDONE RTS

* ----------------------------------
* INITIALIZE MEMLOW & MEMHI & DISREG

INITDISR
 LDA PCLO
 STA MEMLOW  ;UPDATE THE MEMORY POINTER
 LDA PCHI
 STA MEMHI
 LDA PBR  ;GET CURRENT BANK
 STA MEMPBR

* THE FOLLOWING SUBROUTINE DISPLAYS THE CONTENTS OF THE
* REGISTERS AND DISASSEMBLES THE CURRENT INSTRUCTION.
* RETURNS WITH C=1 IF AT A BREAKPOINT

*NOTE, GOT TO DO THIS THE HARD WAY SO IT WORKS WITH PRINTERS,
* DUMB TERMS, ETC.

 JSR VALIDPC  ;IS THE INSTRUCTION OUR BREAK
 BMI NOTBREAK ;NOT OURS OR NOT BREAK
*IS BREAK
 JSR DISBREAK ;DISPLAY "BREAKPOINT"
 LDY YBUFF  ;RESTORE AFTER WRITE
 JSR REPLACE  ;PUT ORIG. INST BACK IN
 STA SBTYPE  ;TYPE OF BRK REPLACED
 CMP #"I"  ;WAS IT IMPLIED BRK ?
 BEQ :DISP  ;IF YES
 INC REALBRK  ;REAL BRK COUNTER
:DISP JSR DISREG2  ;DISASSEMBLE AND DISPLAY
 LDA SBTYPE
 CMP #"I"  ;WAS IT IMPLIED BRK ?
 BEQ :INC  ;IF YES
 LDA #0
 TAY
 JSR STAPCIY  ;PUT REAL BRK BACK IN
:INC INC POINT  ;POINT TO OLD BRK INFO
 LDY YBUFF  ;RESTORE Y

UPDBRKW JSR TRANSFR2 ;UPDATE BRK WINDOW
 DFB DISBRKWC ;code
 LSR BRKWFLG  ;CLEAR FLAG

 JSR WINDDR  ;SET DR WINDOW
 SEC   ;INDICATES A BRK
 RTS   ;LEAVE

* NOT OUR BREAK
NOTBREAK

 JSR DISREG2

* DOES THE BRK WINDOW NEED UPDATING ?
 BIT BRKWFLG
 BPL :NOBRK  ;IF NO
 JSR UPDBRKW  ;IF YES
:NOBRK CLC   ;NO BRK
 RTS   ;RETURN

WRITREG JSR WRITMOR2
:MORE LDA MSGREGA,Y ;GET CHAR
 JSR WRITECK2 ;DISPLAY
 BCC :MORE
 RTS

*NOTE ALL REGISTER MESSAGES MUST BE CONSECUTIVE

DISREG2 LDX #0
 LDY #0
NEXTREG JSR WRITREG
 LDA ACC,X
 JSR TRANSFR2 ;PRINT REG. CONTENTS
 DFB PRBYTEC  ;CODE
 INX
 INX
 CPX #$A  ;TWO BYTES PER REGISTER FOR 16 BIT
 BLT NEXTREG

* PRINT L FLAG. L=0 L/C NOT ENABLED, L=1 L/C BANK1,
* L=2 L/C BANK2

 JSR WRITREG  ;PRINT "L="
 LDX #0
 BIT $C012  ;L/C OR ROM
 BPL LIS0  ;IF ROM
 BIT $C011  ;BANK1 OR 2
 BPL LIS1  ;IF BANK1
 INX   ;BANK2
LIS1 INX
LIS0 TXA
 JSR TRANSFR2 ;PRINT 0,1,OR 2
 DFB PRHEXC  ;CODE
 JSR WRITREG  ;PRINT "P="
 LDA STATUS
 LDX #0
NEXTFLG2
 ASL   ;SHIFT N BIT INTO CARRY
 TAY   ;SAVE A
 BCS FLAGSET
 LDA #"-"
 BNE NOTFLAG
FLAGSET CMP $C800  ;DISABLE EXTRAM
 LDA FLAGS,X  ;LOAD LETTER OF FLAG FROM STRING NVEBDIZC
 CMP $CF00  ;ENABLE EXT RAM
NOTFLAG JSR COUT2  ;
 INX
 TYA   ;RESTORE A
 CPX #8  ;FINISHED YET?
 BLT NEXTFLG2 ;BLO IF NOT FINISHED
 JSR TRANSFR2 ;CARRIAGE RETURN
 DFB CROUTC  ;CODE
 JSR TRANSFR2 ;LIST ONE LINE OF DISASSEMBLED CODE
 DFB DISASMC  ;CODE
 JSR TRANSFR2 ;CHECK FOR ACCESS TO NO ACCESS RANGE
 DFB CKACCESC ;code

* UPDATE FLAG, MEM, EFF & STK WINDOWS
 JSR TRANSFR2 ;UPDATE FLAG,MEM,EFF,STACK WINDOWS
 DFB DISFMESC ;code
 JSR WINDDR
 RTS

* DISPLAY BREAK

DISBREAK
 JSR WRINIT2
:MORE LDA MSGBREAK,Y ;GET CHAR
 JSR WRITECK2 ;DISPLAY
 BCC :MORE
 RTS

******************************
* COMMAND ON
******************************

COMDON BIT OFFFLAG  ;IS DISPLAY OFF ?
 BPL ONIFON  ;IF NO
 LDA #0
 STA OFFFLAG  ;ENABLE DISP TO SCREEN
 JSR TRANSFR2 ;SAVE SCREEN DISPLAY IF INV ON
 DFB SAVEDISPC ;code
ONIFON JSR DISPON  ;DISPLAY ALL WINDOWS
 JMP MAIN102

***** DISPLAY ALL WINDOWS & SET TO WINDDR IF DISPLAY IS ON

DISPON BIT OFFFLAG  ;IS DISPLAY OFF?
 BMI :ISOFF  ;IF YES SKIP DISPLAY

 LSR WINDFLG  ;indicate windows are on

 JSR TRANSFR2 ;SET EXT DISPLAY SWITCHES
 DFB SETSCRNC ;code
 JSR TRANSFR2 ;DISPLAY BORDERS
 DFB DSPBORDRC ;code
 JSR TRANSFR2 ;DISPLAY FLAG,MEM,EFF,STK WINDOWS
 DFB DISFMESC ;code
 JSR TRANSFR2 ;DISPLAY BRK WINDOW
 DFB DISBRKWC ;code
 JSR TRANSFR2 ;DISPLAY PROT WINDOW
 DFB DISPROTWC ;code
 JSR WINDDR  ;SET DR WINDOW
:ISOFF RTS

******************************
*  COMDOFF - TURN EXT DISPLAY OFF
******************************

COMDOFF BIT OFFFLAG  ;DISPLAY ALREADY OFF ?
 BMI :ISOFF  ;IF YES
 JSR TRANSFR2 ;RESTORE DISPLAY SWITCHES
 DFB RESTTEXTC ;code
 LDA #$80
 STA OFFFLAG  ;DON'T DISPLAY TO SCREEN
:ISOFF JMP MAIN102

******************************
*  COMMAND MODE 
******************************

COMDMO EQU *

*--------------------
* Set invisible mode

 LDY #0  ;init for write
 JSR DISMODE  ;display 1st mode choice
 LDA #"1"  ;determine current setting
 BIT INVISIBL
 BNE :INVMO
 LDA #"2"
:INVMO JSR GETCHOIC ;get user's choice
 BEQ :CPUTYP  ;if <CR> entered

 STA INVISIBL ;default to invisible on
 CMP #"2"  ;turn invisible off ?
 BNE :CPUTYP  ;if no
 LDA #0
 STA INVISIBL ;invisible mode off

*---------------------
* Set CPU type

:CPUTYP JSR DISMODE  ;display mode choice
 LDA #"3"  ;determine current type
 BIT CMOSFLAG
 BVS :TYPE  ;65802
 BMI :TYPC02  ;65C02
 LDA #"1"  ;MUST BE 6502
 BNE :TYPE ;<always>
:TYPC02 LDA #"2"
:TYPE JSR GETCHOIC ;get user's choice
 BEQ :TRCBRK  ;if <CR> entered

 LDX #%10000000 ;default to 65c02 mode
 CMP #"1"  ;6502 type ?
 BNE :CK802  ;if no
 LDX #0  ;set 6502 mode

:CK802 CMP #"3"  ;65802 type ?
 BNE :SETCPU  ;if no
 LDX #%01000000 ;set 65802 mode

:SETCPU STX CMOSFLAG ;set new CPU type

*--------------------
* Set trace user break mode

:TRCBRK
 LDA #0
 STA RTBRKFLG ;default to not tracing user breaks

*----------------------
* Set I/O

:IOTYP JSR DISMODE  ;display mode choice
 LDA #"2"
 BIT IOMODE  ;0=NORMAL, BIT7 1=SERIAL, BIT6 1=SLOT1
 BMI :IOMOD  ;if serial
 LDA #"1"
 BVS :IOMOD  ;if printer
 LDA #"3"  ;if normal
:IOMOD JSR GETCHOIC ;get user's choice
 BEQ MODONE  ;if <CR> entered

 CMP #"3"  ;normal I/O ?
 BNE :CKSER  ;if no
 LDA #0
 STA IOMODE  ;screen output
 JMP COMDON ;diplay Main screen

:CKSER CMP #"2" ;serial I/O ?
 BNE :CKPRINT ;if no
 LDA #$80 ;for IOMODE slot #2
 BNE :SETIO ;<always>

:CKPRINT CMP #"1" ;output to slot #1 ?
 BNE MODONE ;if no
 LDA #$40 ;if slot #1
:SETIO STA IOMODE  ;$0=NORMAL, BIT7 1=SERIAL, BIT6 1=SLOT1
 JSR TRANSFR2 ;init slot
 DFB INITPASCC ;code
 JMP COMDOFF ;turn screen display off

MODONE JSR TRANSFR2 ;display flag window
 DFB DISFLGWC ;code
 JSR WINDDR  ;set to DR window
 JMP MAIN102

************ DISMODE **************

*--------------------------------
* Display part of the mode choice menu

DISMODE JSR WRITMOR2 ;write from current Y pointer
:MORE LDA MSGMODE,Y ;DISPLAY MODE MENU
 JSR WRITECK2
 BCC :MORE
 RTS

*---------------------
* Get user choice, display 'Enter <n> : '

GETCHOIC
 PHA   ;save default number
 JSR WRINIT2 ;write from start of message
:MORE LDA MSGMODE2,Y
 JSR WRITECK2 ;display "Enter <"
 BCC :MORE
 PLA  ;restore default
 JSR COUT2 ;display ACC
 JSR WRITMOR2 ;write from current Y pointer
:MORE2 LDA MSGMODE2,Y ;2nd part of message "> :"
 JSR WRITECK2 ;display rest of message
 BCC :MORE2

* Get mode input

 LDA #$A0  ;SPACE
 STA PROMPT  ;NEW PROMPT
 JSR TRANSFR2 ;GET INPUT
 DFB GETLNC  ;CODE
 BCS :ESC  ;if "esc" key
 INX
 LDY #00
 JSR TRANSFR2 ;GET 1ST CHAR
 DFB GETCHRC  ;CODE

 LDY YBUFF   ;restore mode menu pointer
 CMP #CR  ;set z bit if <CR> entered
 RTS

* If "esc" key pressed
:ESC PLA
 PLA   ;pull return address off stack
 JMP MODONE  ;exit MOde command

*--------------------------------
* STA AT (PC,Y) 

STAPCIY PHA
 LDA PBR
 STA PBRADD
 LDA PCHI
 STA HIADD
 LDA PCLO
 STA LOWADD
 PLA
 JSR TRANSFR2 ;STA (LOWADD,Y)
 DFB STAINDYC ;code
 RTS

************ WRITE ***********

* THIS ROUTINE MUST BE BEFORE $CF00

WRINIT2 STY YBUFF  ;SAVE
 LDY #0
WRITMOR2
 CMP $C800  ;DISABLE EXTRAM
 CLC
 RTS

WRITECK2
 CMP $CF00
 INY
 CMP #EOT
 BEQ WRITDON2
 JSR COUT2  ;DISPLAY ON OUTPUT DEVICE
 JMP WRITMOR2
WRITDON2
 RTS   ;ACC CONTAINS LAST CHARACTER DISPLAYED

COUT2 JSR TRANSFR2 ;DISPLAY ON OUTPUT DEVICE
 DFB COUTC  ;code
 RTS

******************************
*  COMDQU - QUIT
******************************

* Allows entering EXT II as a subroutine, doing your 
* debugging and returning to your program.

COMDQU

* RESTORE ALL REGISTERS, DISABLE VIA,
* DO AN RTS BACK TO USER

 SEC
 BCS NOAST

******************************
*  COMD* - MONITOR
******************************

COMDAST EQU *

* DISABLE VIA,
* RESTORE INT VECTORS
*
* GOTO MONITOR

 CLC
NOAST PHP   ;SAVE CARRY FLAG

 LDA REALBRK  ;ANY REAL BRKS IN 
 BEQ :NOREALS ;IF NO
* DISPLAY WARNING MESSAGE
 JSR WRINIT2
:MORBRK LDA MSGREAL,Y
 JSR WRITECK2 ;"**WARNING** REAL BRKS"
 BCC :MORBRK
 LDX #10
:WAIT LDA #0
 JSR TRANSFR2 ;DELAY SO MESSAGE CAN BE READ
 DFB WAITC
 DEX
 BPL :WAIT
:NOREALS
 JSR TRANSFR2 ;RESTORE APPLE RAM
 DFB RESTTEXTC ;CODE
 LDA #$FF
 STA VIAIFR
 LDA #%10000010 ;ENABLE ONLY BUTTON
 STA VIAIER
 PLP   ;GET SAVED CARRY BIT
 LDX STACK  ;USE THIS STACK LOCATION
 TXS

* IF LEAVING WITH "*" COMMAND, DISABLE WRITING TO CARD
 LDA #%11011100 ;CB2 LOW, CB1 POS EDGE, CA2 LOW, CA1 NEG EDGE
 BCC :SETVIA
 LDA #%11011110 ;WRITING TO CARD IS OK WHEN QUiting
:SETVIA STA VIAPCR

 LDX XREG
 LDY YREG
 LDA STATUS
 PHA
 LDA ACC
 BCS :DORTS  ;COMMAND WAS QUIT

 PLP   ;RESTORE STATUS
 JMP MONITOR  ;GO TO APPLE MONITOR

********************
* RETURN TO USER
********************
:DORTS PLP   ;RESTORE STATUS
 RTS   ;RETURN TO USER


*-------------------------------------------------
*SET WINDOW FOR DR

WINDDR
 LDA #0
 STA WINDLEFT
 STA WINDTOP
 STA CURSHORZ ;LEFT EDGE OF WINDOW
 LDA #41
 STA WINDWDTH
 LDA #24
 STA WINDBTM
 LDA #23
 STA CURSVERT ;BOTTOM LINE
 JSR TRANSFR2 ;SET UP BASL BASH
 DFB VTABC  ;CODE
 RTS

* MOVE ROUTINES FROM ROM TO RAM

ROMTORAM
 LDX #15  ;16 BYTES TO MOVE
MOVEMORE
 CMP $C800  ;DISABLE EXT RAM
 LDA CXONTFR,X ;GET BYTE FROM ROM
 CMP $CF00  ;ENABLE EXT RAM
 STA $C880,X  ;PUT IN RAM
 DEX
 BPL MOVEMORE
 LDX #60  ;61 BYTES TO MOVE
MOVEMOR2
 CMP $C800  ;DISABLE EXT RAM
 LDA DATATFR,X ;GET BYTE FROM ROM
 CMP $CF00  ;ENABLE RAM

* INITIALIZE THE ROUTINE FOR THIS SLOT
* BY REPLACING ALL OCCURANCES OF $C8
* WITH $CN.

 CMP #$C8
 BNE MOVEMOR3
 LDA SLOTCN
MOVEMOR3
 STA DATACHK-$3600,X ;PUT IN RAM
 DEX
 BPL MOVEMOR2
 RTS

* REPLACE THE BREAKPOINT IN THE
* PROGRAM WITH THE ORIGINAL INSTRUCTION. REMOVE THE ADDRESS
* FROM THE BREAKS BUFFER, AND REORGANIZE THE LIST.
* ENTER WITH Y POINTING TO BREAKPOINT.

REPLACE TYA
 TAX   ;POINTS AT BRK TO REPLACE
 LDY SLOTN0
 LDA POINT  ;BRK STACK POINTER
 PHA   ;PULLED IN SORTBRK
****************************************
* !!! ALERT !!! SEGMENT DEPENDENT CODE *
****************************************
 LDA #%01100010 ;RAM6, ROM2
 STA SEGMBASE,Y

 LDA BRKTYPE,X
 STA ACC+2  ;SAVE IN RAM6
 CMP #"I"  ;IMPLIED BRK ?
 BEQ SORTBRK  ;IF YES, STAY RAM6, ROM2
 LDA BRKDATA,X ;GET ORIGINAL DATA
 PHA
 LDA BRKPBR,X
 PHA
 LDA BRKHI,X
 PHA
 LDA BRKLOW,X
 PHA
****************************************
* !!! ALERT !!! SEGMENT DEPENDENT CODE *
****************************************
 LDA #%00000010 ;RAM0 ROM2
 STA SEGMBASE,Y
 PLA
 STA LOWADD
 PLA
 STA HIADD
 PLA
 STA PBRADD
 PLA   ;DATA
 LDY #0
 JSR TRANSFR2 ;REPLACE BRK WITH ORIG. DATA
 DFB STAINDYC ;code
 DEC REALBRK  ;DECREMENT REAL BRK COUNT
 LDY SLOTN0
****************************************
* !!! ALERT !!! SEGMENT DEPENDENT CODE *
****************************************
 LDA #%01100010 ;RAM6, ROM2
 STA SEGMBASE,Y

* SORT THE BRK STACK, SHIFT UP DATA TO FILL GAP
SORTBRK STY ACC+1  ;SAVE SLOTN0
 PLA   ;GET BRK STACK POINTER
 STA ACC  ;SAVE IN SEG6

* SAVE THE BRK INFO INCASE WE ARE TRACING THIS BREAK
 LDA BRKPBR,X
 PHA
 LDA BRKHI,X
 PHA
 LDA BRKLOW,X
 PHA
 LDA BRKTGHI,X
 PHA
 LDA BRKTGLOW,X
 PHA
 LDA BRKPASHI,X
 PHA
 LDA BRKPASLO,X
 PHA
 LDA BRKDATA,X
 PHA

:NEXT TXA
 TAY   ;CURRENT BRK Y
 INX   ;NEXT BRK X
 CPX ACC  ;END OF DATA ON STACK ?
 BEQ :SORTEND ;IF YES
 LDA BRKTYPE,X ;SHIFT ALL DATA UP
 STA BRKTYPE,Y
 LDA BRKPBR,X
 STA BRKPBR,Y
 LDA BRKHI,X
 STA BRKHI,Y
 LDA BRKLOW,X
 STA BRKLOW,Y
 LDA BRKTGHI,X
 STA BRKTGHI,Y
 LDA BRKTGLOW,X
 STA BRKTGLOW,Y
 LDA BRKPASHI,X
 STA BRKPASHI,Y
 LDA BRKPASLO,X
 STA BRKPASLO,Y
 LDA BRKDATA,X
 STA BRKDATA,Y
 JMP :NEXT
:SORTEND

* PUT THE INFO FROM THE BRK JUST REPLACED ABOVE THE
* THE CURRENT BRK STACK POINT. TO PUT THE BRK BACK IN
* SIMPLE INCREMENT THE BREAK STACK POINTER BY 1.

 PLA
 STA BRKDATA,Y
 PLA
 STA BRKPASLO,Y
 PLA
 STA BRKPASHI,Y
 PLA
 STA BRKTGLOW,Y
 PLA
 STA BRKTGHI,Y
 PLA
 STA BRKLOW,Y
 PLA
 STA BRKHI,Y
 PLA
 STA BRKPBR,Y

 LDA ACC+2  ;BRKTYPE
 STA BRKTYPE,Y
 PHA

 LDX ACC+1  ;SLOTN0
****************************************
* !!! ALERT !!! SEGMENT DEPENDENT CODE *
****************************************
 LDA #%00000010 ;RAM0, ROM2
 STA SEGMBASE,X
 STY POINT  ;NEW BRK STACK POINTER
 PLA   ;TYPE OF BRK REMOVED
 RTS

***********************************
* DECREMENT TOGO IF VALID BREAK
* TOGOFLG = 0 IF TOGO = 0
***********************************

* USE CURRENT PC

DECTGPC JSR PC2LETR  ;LOAD LETTER 3,2,1 WITH PC

DECTOGO LDA #0  ;DEC TOGO FLAG
 BEQ VALID2

***********************************
*CHECK IF ADDRESS IS VALID BREAKPOINT ON LIST.
*RETURNS WITH N=1 IF INVALID, Z=1 IF VALID AND REAL BRK
* LETTER 3,2,1 MUST CONTAIN THE INSTRUCTION ADDRESS
***********************************

* USE CURRENT PC

VALIDPC JSR PC2LETR  ;LOAD LETTER 3,2,1 WITH PC

VALIDAD LDA #$80  ;DON'T DEC TOGO
VALID2 PHA   ;SAVE TOGO FLAG
 LDA #$80
 STA TOGOFLG  ;RESET TOGO FLAG
 STY YBUFF  ;SAVE Y
 STX XBUFF  ;SAVE X
 LDY POINT  ;GET BREAKS POINTER
 DEY   ;ARE THERE ANY BREAKS ?
 BPL :BRKS  ;IF YES
 PLA   ;CLEAN UP STACK
 TYA   ;SET STATUS FLAGS
 RTS   ;IF NO

:BRKS INY

 LDA LETTER3  ;PBR OF BRK ADDRESS
 PHA
 LDA LETTER2  ;HI BYTE
 PHA
 LDA LETTER1  ;LOW BYTE
 PHA
 LDX SLOTN0

****************************************
* !!! ALERT !!! SEGMENT DEPENDENT CODE *
****************************************

 LDA #%01100010 ;RAM6, ROM2
 STA SEGMBASE,X
 PLA
 STA ACC+2  ;STORE IN RAM SEG6
 PLA
 STA ACC+1
 PLA
 STA ACC
 PLA   ;GET DEC TOGO FLAG
 STA ACC+3
 LDA #$80
 STA ACC+4  ;USE THIS AS TOGOFLG
:LOOPLO DEY
 BMI :LEAVE  ;INVALID N=1
 LDA ACC+2  ;LOW BYTE
 CMP BRKLOW,Y ;MATCH ?
 BNE :LOOPLO  ;IF NO

 LDA ACC+1  ;HI BYTE
 CMP BRKHI,Y  ;HI BYTES MATCH ?
 BNE :LOOPLO  ;IF NO

 LDA ACC  ;PBR BYTE
 CMP BRKPBR,Y ;MATCH ?
 BNE :LOOPLO  ;IF NO, IF VALID FALL THROUGH

 LDA ACC+3  ;DEC TOGO ?
 BMI :CKREAL  ;IF NO

* DECREMENT TOGO COUNT

 SEC
 LDA BRKTGLOW,Y
 SBC #1
 STA BRKTGLOW,Y
 LDA BRKTGHI,Y
 SBC #0
 STA BRKTGHI,Y

* DOES TOGO = 0 ?
 BNE :CKREAL  ;TOGO NOT 0
 LDA BRKTGLOW,Y
 BNE :CKREAL  ;TOGO NOT 0

* ACC = 0
 STA ACC+4  ;TOGO = 0

 LDA BRKPASHI,Y
 STA BRKTGHI,Y ;RESET TOGO
 LDA BRKPASLO,Y
 STA BRKTGLOW,Y

:CKREAL LDA #"R"
 CMP BRKTYPE,Y ;Z=1 IF REAL BRK
:LEAVE PHP   ;SAVE FLAGS
 LDA ACC+4  ;TOGO FLAG
 PHA

****************************************
* !!! ALERT !!! SEGMENT DEPENDENT CODE *
****************************************

 LDA #%00000010 ;RAM0, ROM2
 STA SEGMBASE,X

 PLA   ;GET TOGO FLAG
 STA TOGOFLG  ;SET FLAG
 LDX XBUFF  ;RESTORE X
 PLP   ;RESTORE FLAGS
*ON VALID RETURN Y IS POINTING TO ADDRESS
* IN BREAKS BUFFER.
 RTS

* PUT CURRENT PC INTO LETTER 3,2,1

PC2LETR LDA PBR
 STA LETTER3
 LDA PCHI
 STA LETTER2
 LDA PCLO
 STA LETTER1
 RTS

****** SAVE THE ACC, X AND P REGISTERS *****

SAVEAXP2
 PHP   ;SAVE STATUS
 STX XSAVESEG
 STA ASAVESEG
 PLA   ;GET STATUS
 STA PSAVESEG ;SAVE
 RTS

****** RESTORE THE ACC, X AND P REGISTERS *****

RESTAXP2
 LDX XSAVESEG
 LDA PSAVESEG
 PHA
 LDA ASAVESEG
 PLP
 RTS

***** THIS SEGMENTS GLOBAL SUBROUTINES *****

SUBTABL2

PUTBREAKC EQU *-SUBTABL2*4+2+$100
 DA PUTBREAK-1

UPDATEC EQU *-SUBTABL2*4+2+$100
 DA UPDATE-1

INITDISRC EQU *-SUBTABL2*4+2+$100
 DA INITDISR-1

DISBREAKC EQU *-SUBTABL2*4+2+$100
 DA DISBREAK-1

ROMTORAMC EQU *-SUBTABL2*4+2+$100
 DA ROMTORAM-1

DISPONC EQU *-SUBTABL2*4+2+$100
 DA DISPON-1

WINDDRC  EQU *-SUBTABL2*4+2+$100
 DA WINDDR-1

DECTGPCC EQU *-SUBTABL2*4+2+$100
 DA DECTGPC-1

DECTOGOC EQU *-SUBTABL2*4+2+$100
 DA DECTOGO-1

VALIDPCC EQU *-SUBTABL2*4+2+$100
 DA VALIDPC-1

VALIDADC EQU *-SUBTABL2*4+2+$100
 DA VALIDAD-1

REPLACEC EQU *-SUBTABL2*4+2+$100
 DA REPLACE-1

STAPCIYC EQU *-SUBTABL2*4+2+$100
 DA STAPCIY-1

**********************************
* SEGMENT CROSSOVER AREA
**********************************

 LST ON
S2END = $CF9D-*
 do nolist
 LST OFF
 fin
 ERR *-1/$CF9D
 DS $CF9D-*,$FF

MAIN102 JSR SAVEAXP2 ;COME HERE TO TRANSFER TO SEGMENT0 DIRECTLY
 LDX SLOTN0
 LDA #%00000101 ;RAM0,ROM5
 STA SEGMBASE,X ;NEXT INSTRUCTION EXECUTED FROM SEGMENT 5
 JSR RESTAXP2 ;RESTORE AFTER TRANSFER FROM SEGMENT 5
 RTS  ;GOTO COMMANDS IN THIS SEGMENT
 NOP
 NOP  ;MATCH LENGTH WITH SEG 5

* TRANSFER TO OTHER SEGMENTS

TRANSFR2

 JSR SAVEAXP2
 PLA   ;GET RETRUN ADDRESS FROM STACK
 CLC
 ADC #1  ;INC TO POINT AT CODE BYTE
 STA TEMPSEG  ;SETUP LDA TEMPSEG ROUTINE
 PLA
 ADC #0  ;ADD CARRY, IF ANY
 STA TEMPSEG+1 ;SETUP LDA TEMPSEG ROUTINE
 PHA
 LDA TEMPSEG
 PHA   ;BUMP RETURN ADDRESS PAST CODE BYTE
 LDA #2  ;CURRENT SEG #
 PHA
 JSR LDATEMP  ;LOAD CODE BYTE
 STA SEGMCODE ;SAVE CODE
 AND #$07  ;STRIP ALL BUT SEG #
 LDX SLOTN0
 STA SEGMBASE,X ;NEXT INSTR. RUN FROM NEW SEGMENT
* NEW SEGMENT
 LDA #>RETURN2 ;WHERE TO RETURN TO
 PHA
 LDA #RETURN2
 PHA
 LDA SEGMCODE ;CODE BYTE
 AND #$F8  ;STIP OFF SEG# LEAVING SUB #
 LSR
 LSR   ;LEAVE SUB# MULTIPLIED BY 2
* GET ADDRESS OF SUB FROM SUBTABL & PUSH ON STACK
 TAX
 LDA SUBTABL2+1,X
 PHA
 LDA SUBTABL2,X
 PHA

 JSR RESTAXP2 ;RESTORE REGISTERS
 RTS   ;USE RTS TO GOTO SUB

* RETURN HERE FROM SUBROUTINE

RETURN2 EQU *-1
 JSR SAVEAXP2
 PLA   ;SEG # TO RETURN TO
 LDX SLOTN0
 STA SEGMBASE,X ;RETURN TO SEGMENT
 JSR RESTAXP2
 RTS   ;RETURN TO PROGRAM

 DS \,$FF ;PUT OBJECT AT NEXT PAGE
